package com.superb.allocation.utils;

import com.aliyun.oss.*;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.OSSObject;
import com.superb.allocation.service.oss.BucketService;
import com.superb.allocation.service.oss.UploadService;
import com.superb.allocation.service.oss.impl.BucketServiceImpl;
import com.superb.allocation.service.oss.impl.UploadServiceImpl;
import com.superb.common.core.enums.SuperbCode;
import com.superb.common.core.exception.SuperbException;
import com.superb.common.properties.AliyunProperties;
import com.superb.common.utils.HeardersUtils;
import com.superb.common.utils.SpringContextUtils;
import jakarta.servlet.ServletOutputStream;

import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Date;

/**
 * @Author: ajie
 * @CreateTime: 2024-07-04 15:25
 */
public class AliyunOssUtils {

    private static String getBucket() {
        return HeardersUtils.getHeader("bucket", () -> "zlgyl");
    }

    /**
     * 上传
     * @return
     */
    public static UploadService upload() {
        // 如果桶不存在-创建
        bucket().createBucket();
        return new UploadServiceImpl(getClient());
    }

    /**
     * 桶
     * @return
     */
    public static BucketService bucket() {
        return new BucketServiceImpl(getClient());
    }

    /**
     * 私有对象获取公网url
     * @return
     */
    public static String getUrl(String key) {
        try {
            // 指定生成的签名URL过期时间，单位为毫秒。本示例以设置过期时间为1小时为例。
            Date expiration = new Date(new Date().getTime() + 3600 * 1000L);
            // 生成签名URL。
            GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(getBucket(), key, HttpMethod.GET);
            // 设置过期时间。
            request.setExpiration(expiration);
            // 通过HTTP GET请求生成签名URL。
            URL signedUrl = getClient().generatePresignedUrl(request);
            return signedUrl.toURI().toString();
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        } catch (OSSException oe) {
            throw new SuperbException(SuperbCode.ALIYUN_OSS_UPLOAD, oe.getMessage());
        } catch (ClientException ce) {
            throw new SuperbException(SuperbCode.ALIYUN_OSS_CLIENT, ce.getMessage());
        } finally {
            getClient().shutdown();
        }
    }

    /**
     * 预览
     * @return
     */
    public static void view(String key, ServletOutputStream outputStream) {
        try {
            OSSObject object = getClient().getObject(getBucket(), key);
            String suffix = key.substring(key.lastIndexOf(".") + 1);
            InputStream inputStream = object.getObjectContent();
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
            outputStream.close();
            inputStream.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (OSSException oe) {
            throw new SuperbException(SuperbCode.ALIYUN_OSS_UPLOAD, oe.getMessage());
        } catch (ClientException ce) {
            throw new SuperbException(SuperbCode.ALIYUN_OSS_CLIENT, ce.getMessage());
        } finally {
            getClient().shutdown();
        }
    }

    /**
     * 获取连接对象
     *
     * @return
     */
    public static OSS getClient() {
        AliyunProperties properties = SpringContextUtils.getBean(AliyunProperties.class);
        AliyunProperties.Oss oss = properties.getOss();
        return new OSSClientBuilder().build(oss.getEndpoint(), properties.getAccessKeyId(), properties.getAccessKeySecret());
    }

}
